using B.S.NewMedical.Api.Write.Application.Command.Department;
using B.S.NewMedical.Domain.Doctor;
using B.S.NewMedical.ErrorCode;
using B.S.NewMedical.Infrastructure.Interface;
using MediatR;
using Microsoft.Extensions.Logging;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace B.S.NewMedical.Api.Write.Application.Handler.Department
{
    /// <summary>
    /// 更新科室处理器
    /// 处理更新科室的业务逻辑，包括数据验证、更新等操作
    /// </summary>
    public class UpdateDepartmentsHandler : IRequestHandler<UpdateDepartmentsCommand, ApiResult<int>>
    {
        private readonly IBaseRepository<DepartmentModel> _departmentRepository;
        private readonly ILogger<UpdateDepartmentsHandler> _logger;

        /// <summary>
        /// 构造函数
        /// 注入依赖的服务
        /// </summary>
        /// <param name="departmentRepository">科室仓储接口</param>
        /// <param name="logger">日志记录器</param>
        public UpdateDepartmentsHandler(IBaseRepository<DepartmentModel> departmentRepository, ILogger<UpdateDepartmentsHandler> logger)
        {
            _departmentRepository = departmentRepository;
            _logger = logger;
        }

        /// <summary>
        /// 处理更新科室命令
        /// 执行更新科室的业务逻辑
        /// </summary>
        /// <param name="request">更新科室命令</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>操作结果，包含更新的科室ID</returns>
        public async Task<ApiResult<int>> Handle(UpdateDepartmentsCommand request, CancellationToken cancellationToken)
        {
            try
            {
                _logger.LogInformation("开始处理更新科室命令，科室ID: {DepartmentId}, 科室名称: {DepartmentName}", 
                    request.Id, request.DepartmentName);

                // 业务验证
                var validationResult = await ValidateRequest(request);
                if (validationResult.Code != ApiEnum.Success)
                {
                    _logger.LogWarning("更新科室请求验证失败: {ErrorMessage}", validationResult.Msg);
                    return validationResult;
                }

                // 检查科室是否存在
                var existingDepartment = _departmentRepository.GetAll()
                    .FirstOrDefault(d => d.Id == request.Id && !d.IsDeleted);
                
                if (existingDepartment == null)
                {
                    _logger.LogWarning("科室不存在: {DepartmentId}", request.Id);
                    return new ApiResult<int>
                    {   
                        Code = ApiEnum.Fail,
                        Msg = $"科室ID {request.Id} 不存在"
                    };
                }

                // 检查科室名称是否已被其他科室使用
                var duplicateDepartment = _departmentRepository.GetAll()
                    .FirstOrDefault(d => d.DepartmentName == request.DepartmentName && 
                                       d.Id != request.Id && 
                                       !d.IsDeleted);
                
                if (duplicateDepartment != null)
                {
                    _logger.LogWarning("科室名称已被其他科室使用: {DepartmentName}", request.DepartmentName);
                    return new ApiResult<int>
                    {
                        Code = ApiEnum.Fail,
                        Msg = $"科室名称 '{request.DepartmentName}' 已被其他科室使用"
                    };
                }

                // 更新科室实体
                existingDepartment.DepartmentName = request.DepartmentName.Trim();
                existingDepartment.Type = request.Type ?? existingDepartment.Type;
                existingDepartment.ParetId = request.ParentId;
                existingDepartment.DepartmentAddr = request.DepartmentAddr.Trim();
                existingDepartment.RegistrationFee = request.RegistrationFee;
                existingDepartment.IsEmergencyService = request.IsEmergencyService;
                existingDepartment.IsOnline = request.IsOnline;
                existingDepartment.remark = request.Remark;

                // 保存到数据库
                var result = await _departmentRepository.UpdateAsync(existingDepartment);

                _logger.LogInformation("科室更新成功，科室ID: {DepartmentId}, 科室名称: {DepartmentName}", 
                    request.Id, request.DepartmentName);

                return new ApiResult<int>
                {
                    Code = ApiEnum.Success,
                    Msg = "科室更新成功",
                    Data = result
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "更新科室时发生异常，科室ID: {DepartmentId}, 科室名称: {DepartmentName}", 
                    request.Id, request.DepartmentName);
                return new ApiResult<int>
                {
                    Code = ApiEnum.Error,
                    Msg = $"更新科室失败: {ex.Message}"
                };
            }
        }

        /// <summary>
        /// 验证请求参数
        /// 检查请求参数的合法性
        /// </summary>
        /// <param name="request">更新科室命令</param>
        /// <returns>验证结果</returns>
        private async Task<ApiResult<int>> ValidateRequest(UpdateDepartmentsCommand request)
        {
            // 验证科室ID
            if (request.Id <= 0)
            {
                return new ApiResult<int>
                {
                    Code = ApiEnum.Fail,
                    Msg = "科室ID无效"
                };
            }

            // 验证科室名称
            if (string.IsNullOrWhiteSpace(request.DepartmentName))
            {
                return new ApiResult<int>
                {
                    Code = ApiEnum.Fail,
                    Msg = "科室名称不能为空"
                };
            }

            if (request.DepartmentName.Length > 50)
            {
                return new ApiResult<int>
                {
                    Code = ApiEnum.Fail,
                    Msg = "科室名称长度不能超过50个字符"
                };
            }

            // 验证科室地址
            if (string.IsNullOrWhiteSpace(request.DepartmentAddr))
            {
                return new ApiResult<int>
                {
                    Code = ApiEnum.Fail,
                    Msg = "科室地址不能为空"
                };
            }

            if (request.DepartmentAddr.Length > 200)
            {
                return new ApiResult<int>
                {
                    Code = ApiEnum.Fail,
                    Msg = "科室地址长度不能超过200个字符"
                };
            }

            // 验证挂号费
            if (request.RegistrationFee < 0)
            {
                return new ApiResult<int>
                {
                    Code = ApiEnum.Fail,
                    Msg = "挂号费不能为负数"
                };
            }

            if (request.RegistrationFee > 10000)
            {
                return new ApiResult<int>
                {
                    Code = ApiEnum.Fail,
                    Msg = "挂号费不能超过10000元"
                };
            }

            // 验证父级ID
            if (request.ParentId > 0)
            {
                var parentDepartment = _departmentRepository.GetAll()
                    .FirstOrDefault(d => d.Id == request.ParentId && !d.IsDeleted);
                
                if (parentDepartment == null)
                {
                    return new ApiResult<int>
                    {
                        Code = ApiEnum.Fail,
                        Msg = "指定的父级科室不存在"
                    };
                }
            }

            return new ApiResult<int>
            {
                Code = ApiEnum.Success,
                Msg = "验证通过",
                Data = 0
            };
        }
    }
} 